/****************************************************************************************
*            . .. .                                                                     *
*                    ...                                                                *
*                       .":                                                             *
*   .                      u                                                            *
* ..     .:uxkkOkkx=.      "k'                                                          *
*.     "k00O0ko==uk00x'     OO.                       IBE-CAE                           *
*'   .xK0O00: 'xx" x0Ku    .O0:     Copyright (C) by Internet Based Engineering         *
*   .O0OO00= oKOk:"O0O'    :00=                 All rights reserved.                    *
*.  =0OOO00" =OOO0Oo'     =0OO:                      www.ibe.cn                         *
*.  u0OOOO0O'          .o00OOO.                                                         *
* . :KOOOOO00xu=:::=uok00OOOO"                                                          *
*   .x00OOOOOO0000000OOOOOOx.                                                           *
*    .u00OOOOOOOOOOOOOOOOO=                                                             *
*      .ukOOOOOOOOOOOOku'                                                               *
*          .'::==::'.                                                                   *
****************************************************************************************/

#ifndef IBE_BLOCK_H_
#define IBE_BLOCK_H_

#include <string>

#include "IBE_Object.h"

namespace ibe_common
{
    /**
    * @class IBE_Block
    * @brief 网格集信息
    * @author liupeng
    */
    class IBE_COMMON_EXPORT IBE_Block : public IBE_Object
    {
    public:
        explicit IBE_Block();
        ~IBE_Block();
        IBE_TypeMacro( ibe_common, IBE_Block, ibe_common, IBE_Object );

        /**
         * @brief 单元集类型
         */
        enum IBE_BlockType
        {
            IBE_BLOCK_POINT_SET = 0,    //!< 节点集
            IBE_BLOCK_ELEMENT_SET,      //!< 单元集
            IBE_BLOCK_SUB_ELEMENT_SET   //!< 子单元集（SubElementSet）
        };

        /**
        * @brief 子单元的单元类型
        */
        enum IBE_SubElementType
        {
            IBE_SUB_ELEMENT_POINT = 0,  //!< 点
            IBE_SUB_ELEMENT_EDGE,       //!< 边
            IBE_SUB_ELEMENT_FACE        //!< 面
        };

        //@{
        virtual void SetBlockName( const char* name );
        virtual const char* GetBlockName()
        {
            return this->blockName_.c_str();
        }
        //@}

        //@{
        /**
         * @brief 设置单元集信息
         *
         * @param blockType 单元集类型，IBE_BlockType的枚举值
         * @param indexsNum indexs数组长度
         * @param indexs 网格集节点/单元索引号数组
         * @param subIndexs 子单元在原始单元内的位置或者索引号数组，长度为indexsNum，blockType为子单元集（IBE_BlockType::IBE_BLOCK_SUB_ELEMENT_SET）时才有
         * @param subTypes 子单元类型数组，长度为indexsNum，IBE_SubElementType的枚举值，blockType为子单元集（IBE_BlockType::IBE_BLOCK_SUB_ELEMENT_SET）时才有
         */
        virtual void SetBlockData( const int blockType, const int64_t indexsNum, int64_t* indexs,
                                   uint8_t* subIndexs = nullptr, uint8_t* subTypes = nullptr );
        virtual void SetBlockType( const int blockType );
        virtual int GetBlockType()
        {
            return this->blockType_;
        }
        virtual int64_t GetNumberOfIndexs()
        {
            return this->numOfIndexs_;
        }
        virtual int64_t* GetIndexs()
        {
            return this->indexs_;
        }
        virtual int64_t GetNumberOfSubIndexs()
        {
            return this->numOfSubIndexs_;
        }
        virtual uint8_t* GeSubIndexs()
        {
            return this->subIndexs_;
        }
        virtual uint8_t* GeSubTypes()
        {
            return this->subTypes_;
        }
        //@}

        virtual void Initialize() override;
        virtual void InitBlockData();

        virtual void Copy( ibe_common::IBE_Object* obj ) override;

    protected:
        std::string blockName_; //!< 网格集名称
        int blockType_; //!< 单元集类型，IBE_Block::IBE_BlockType枚举值
        /**
         * blockType为节点集时，表示节点索引号数组；
         * blockType为单元集时，表示单元索引号数组；
         * blockType为子单元集时，表示原始单元索引号数组；
         */
        int64_t* indexs_;
        int64_t numOfIndexs_;
        //! 子单元在原始单元内的位置或者索引号数组，blockType为子单元集时才有
        uint8_t* subIndexs_;
        int64_t numOfSubIndexs_;
        //! 子单元的单元类型，blockType为子单元集时才有
        uint8_t* subTypes_;

    private:
        IBE_Block( const IBE_Block& ) = delete;
        IBE_Block& operator=( const IBE_Block& ) = delete;
    };
} // namespace ibe_common

#endif // IBE_BLOCK_H_